package geppetto.phraseTable.builder;

import geppetto.phraseHMM.WordTrie;
import geppetto.phraseTable.phrase.Phrase;
import geppetto.phraseTable.phrase.feature.AbstractFeature;
import geppetto.phraseTable.phrase.feature.calc.local.AbstractFeatureCalc;
import geppetto.phraseTable.phrase.feature.global.AbstractGlobalFeatureCalc;
import geppetto.phraseTable.prunning.local.AbstractPhrasePrunner;

import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;


public class PhraseTableBuilder {

	ExtractionFileReader reader;
	List<AbstractFeatureCalc> featureCalcs = new ArrayList<AbstractFeatureCalc>();
	List<AbstractGlobalFeatureCalc> posFeatureCalcs = new ArrayList<AbstractGlobalFeatureCalc>();
	List<AbstractPhrasePrunner> prunners = new ArrayList<AbstractPhrasePrunner>();
	WordTrie sourceVocab;
	WordTrie targetVocab;
	
	protected boolean useAdditionalInformation = false;
	public PhraseTableBuilder(ExtractionFileReader reader, WordTrie sourceVocab, WordTrie targetVocab) {
		super();
		this.reader = reader;
		this.sourceVocab = sourceVocab;
		this.targetVocab = targetVocab;
	}

	public void addCalc(AbstractFeatureCalc calc){
		featureCalcs.add(calc);
	}
	
	public void addPrunner(AbstractPhrasePrunner prunner){
		prunners.add(prunner);
	}

	public void mergePhrases(){
	}

	public void write(PhraseWriter writer) throws NumberFormatException, IOException {
		while (reader.read()) {
			ArrayList<Phrase> phrases = new ArrayList<Phrase>();
			//ArrayList<String> sources = new ArrayList<String>();
			//ArrayList<String> targets = new ArrayList<String>();
			ArrayList<String> remainders = new ArrayList<String>();
			for(int i = 0; i < reader.getSourceArray().size(); i++){
				int[] source = WordTrie.stringToIntArray(reader.getSourceArray().get(i));
				int[] target = WordTrie.stringToIntArray(reader.getTargetArray().get(i));				
				Phrase p = new Phrase(sourceVocab.getPhraseId(source), 
						targetVocab.getPhraseId(target), 1);
				if(p._targetPhraseID == -1 && p._sourcePhraseID == -1){
					for(int k = 0; k < source.length; k++){
						System.out.print(source[k]+" ");
					}
					System.out.print("- ");
					for(int k = 0; k < target.length; k++){
						System.out.print(target[k] + " ");
					}
					System.out.print("- ");
					System.out.print(p._sourcePhraseID + " ");
					System.out.print(p._targetPhraseID + " ");
					System.out.println();
				}
				p.setSourceLen(source.length);
				p.setTargetLen(target.length);
				phrases.add(p);
				p.set_data(reader.getDataArray().get(i));
//				sources.add(source);
//				targets.add(target);
				remainders.add(reader.getRemainderArguments().get(i));
			}
			for(AbstractFeatureCalc calc : featureCalcs){
				calc.calculateFeature(phrases);				
			}
			for(int i = 0; i < phrases.size(); i++){				
				Phrase p = phrases.get(i);
				boolean pruneEntry = false;
				for(AbstractPhrasePrunner prunner : prunners){
					if(prunner.shouldPruneEntry(p)){
						pruneEntry = true;
						break;
					}
				}
				
				if(!pruneEntry)
				{
					/*String entry = sources.get(i) + " ||| " + targets.get(i) + " ||| " + p.getFeaturesMoses();
					if(useAdditionalInformation){
						entry += " ||| " + remainders.get(i);
					}
					printStream.println(entry);*/
					writer.writePhrase(p);
				}
			}
		}
	}

	public void setUseAdditionalInformation(boolean useAdditionalInformation) {
		this.useAdditionalInformation = useAdditionalInformation;
	}	
}
